const fs = require("fs-extra");
const { isObject, cloneDeep } = require("lodash");
const path = require("path");

async function getTranslateRows(language, translates, result, parents = []) {
  for (const key in translates) {
    const value = translates[key];
    if (isObject(value)) {
      parents.push(key);
      await new Promise((resolve) => setTimeout(resolve, 0));
      await getTranslateRows(language, value, result, parents);
      parents.pop();
    } else {
      const _key = parents.concat(key).join(".");
      if (!result[_key]) result[_key] = {};
      result[_key][language] = value;
    }
  }
  return result;
}

async function getI18nTranslates(languageDir, onlyLanguages = false) {
  const languages = [];
  const i18n = {};
  const translates = {};
  const files = await fs.readdir(languageDir, { withFileTypes: true }).catch(() => []);

  for (const file of files) {
    const res = path.parse(file.name);

    if (!file.isFile() || res.ext !== ".json" || /[\u4e00-\u9fa5]+/.test(res.name)) continue;

    languages.push(res.name);

    if (onlyLanguages) continue;

    const content = (await fs.readFile(path.join(file.parentPath, file.name))).toString("utf8");

    i18n[res.name] = JSON.parse(content);
  }

  if (!onlyLanguages) {
    for (const language of languages) {
      await getTranslateRows(language, i18n[language], translates);
    }
  }

  return { languages, translates };
}

function mergeTranslates(i18n, translated, force = false) {
  const merged = cloneDeep(i18n);

  for (const key in translated) {
    if (merged[key]) {
      for (const language in translated[key]) {
        if (force || (!force && !merged[key][language])) {
          merged[key][language] = translated[key][language];
        }
      }
    } else {
      merged[key] = translated[key];
    }
  }

  return merged;
}

module.exports = { getI18nTranslates, mergeTranslates };
